<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>校园调解沙盘</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            margin: 20px;
        }
        #chat-container {
            border: 1px solid #ccc;
            padding: 10px;
            height: 400px;
            overflow-y: auto;
            margin-bottom: 10px;
        }
        #message-input {
            width: 70%;
            padding: 5px;
        }
        button {
            padding: 5px 10px;
            margin-left: 5px;
        }
    </style>
</head>
</body>
<body>
    <h1>校园调解沙盘</h1>
    <div id="chat-container"></div>
    <input type="text" id="message-input" placeholder="请输入你的问题">
    <button onclick="sendMessage()">发送</button>
    <!-- 添加控制语音的按钮 -->
    <button id="voice-control-btn" onclick="controlVoice()">暂停语音</button>

    <!-- 添加沙盘容器 -->
    <div id="sandbox" style="position: fixed; bottom: 0; left: 0; width: 100%; height: 300px; background: url('sand-texture.jpg'); background-size: cover; z-index: -1;"></div>

    <script>
        let isPaused = false;
        const synth = window.speechSynthesis;

        function sendMessage() {
            // 停止当前的语音朗读
            synth.cancel();
            isPaused = false;
            document.getElementById('voice-control-btn').textContent = '暂停';

            const input = document.getElementById('message-input');
            const message = input.value;
            if (message.trim() === '') return;

            // 显示用户消息
            const chatContainer = document.getElementById('chat-container');
            const userDiv = document.createElement('div');
            userDiv.textContent = `你: ${message}`;
            chatContainer.appendChild(userDiv);

            // 显示请稍后的提示
            const waitingDiv = document.createElement('div');
            waitingDiv.textContent = '正在淘沙子，请稍后...';
            chatContainer.appendChild(waitingDiv);

            // 发送请求，确保地址正确
            const apiUrl = 'http://127.0.0.1:5001/chat';
            fetch(apiUrl, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({ message: message })
            })
           .then(response => {
                if (!response.ok) {
                    throw new Error(`HTTP 错误! 状态码: ${response.status}`);
                }
                return response.json();
            })
           .then(data => {
                // 移除请稍后的提示
                chatContainer.removeChild(waitingDiv);
                if (data.error) {
                    const errorDiv = document.createElement('div');
                    errorDiv.textContent = `错误: ${data.error}`;
                    chatContainer.appendChild(errorDiv);
                } else {
                    const botDiv = document.createElement('div');
                    botDiv.textContent = `沙盘助手: ${data.response}`;
                    chatContainer.appendChild(botDiv);

                    // 使用 Web Speech API 朗读回复内容
                    const utterance = new SpeechSynthesisUtterance(data.response);
                    // 设置语言为中文
                    utterance.lang = 'zh-CN'; 
                    synth.speak(utterance);
                }
            })
           .catch(error => {
                // 移除请稍后的提示
                chatContainer.removeChild(waitingDiv);
                console.error('请求出错:', error);
                const errorDiv = document.createElement('div');
                errorDiv.textContent = `请求出错: ${error.message}`;
                chatContainer.appendChild(errorDiv);
            });

            input.value = '';
        }

        function controlVoice() {
            if (synth.speaking) {
                if (isPaused) {
                    synth.resume();
                    document.getElementById('voice-control-btn').textContent = '暂停';
                } else {
                    synth.pause();
                    document.getElementById('voice-control-btn').textContent = '继续';
                }
                isPaused = !isPaused;
            }
        }
        const sandbox = document.getElementById('sandbox');
        const clickCounts = new Map();
        const quotes = [
            "每一个不曾起舞的日子，都是对生命的辜负。——尼采",
            "世界上只有一种真正的英雄主义，那就是在recognize life的真相后依然热爱生活。——罗曼·罗兰",
            "生活是一面镜子，你透过它看到的未必是自己的真实，不过，至少你明白了，自己并非不可改变。——塞林格",
            "每个人都有自己的生活方式，不要为了迎合他人而改变自己的生活方式。——塞林格",
            "生活是一场马拉松，你必须在途中找到自己的速度。——塞林格",
            "人类最大的弱点，是自我否定的恐惧。——荣格",
            "生命的意义在于设身处地替人着想，忧他人之忧，乐他人之乐。——爱因斯坦",
            "自由不是让你想做什么就做什么，自由是教你不想做什么就可以不做什么。——康德",
            "一个人知道自己为什么而活，就可以忍受任何一种生活。——尼采",
            "过去属于死神，未来属于你自己。——雪莱",
            "幸福是把灵魂安放在最适当的位置。——亚里士多德",
            "未经审视的人生不值得过。——苏格拉底",
            "存在即合理。——黑格尔",
            "生活是一个过程，不是一个目标。——康德",
            "当你凝视深渊时，深渊也在凝视着你。——尼采",
            "生活是一个不断变化的过程，我们必须适应这个过程。——塞林格",
            "爱不是彼此凝视，而是一起注视同一个方向。——圣埃к苏佩里",
            "真正的发现之旅不在于寻找新的风景，而在于拥有新的眼睛。——普鲁斯特",
            "人生而自由，却无往不在枷锁之中。——卢梭",
            "万物皆有裂痕，那是光进来的地方。——莱昂纳德·科恩",
            "最黑暗的夜晚也会迎来清晨。——雨果",
            "人生如逆旅，我亦是行人。——苏轼",
            "每个人都自己的生活方式，不要为了迎合他人而改变自己的生活方式。",
            "生活是一场马拉松，你必须在途中找到自己的速度。",
            "自由不是让你想做什么就做什么，自由是教你不想做什么就可以不做什么。",
            "一个人知道自己为什么而活，就可以忍受任何一种生活。",
            "过去属于死神，未来属于你自己。",
            "幸福是把灵魂安放在最适当的位置。",
            "未经审视的人生不值得过。",
            "存在即合理。",
            "生活是一个过程，不是一个目标。",
            "知者不言，言者不知。——老子",
            "所有的战争都是内战，因为所有的人类都是同胞。——弗朗索瓦·费奈隆",
            "生活是一个不断变化的过程，我们必须适应这个过程。",
            "爱不是彼此凝视，而是一起注视同一个方向。",
            "真正的发现之旅不在于寻找新的风景，而在于拥有新的眼睛。",
            "人生而自由，却无往不在枷锁之中。",
            "他人即地狱。——萨特",
            "活在当下，因为除了此刻，你一无所有。——达芬奇",
            "你的时间有限，别浪费生命活在他人的剧本里。——史蒂夫·乔布斯",
            "希望是件好东西，也许是世间最好的东西，好东西永远不会消逝。——斯蒂芬·金",
            "你担心什么，什么就控制你。——约翰·洛克",
            "生活是等待行动时的艺术。——哈罗德·品特",
            "不要温和地走进那个良夜。——狄兰·托马斯",
            "我们一路奋战，不是为了改变世界，而是为了不让世界改变我们。——《熔炉》",
            "只有一种方式能避免批评：什么也不做，什么也不说，成为什么都不是的人。——亚里士多德",
            "最可怕的敌人，就是没有坚强的信念。——罗曼·罗兰",
            "人的一切痛苦，本质上都是对自己无能的愤怒。——王小波",
            "所谓成长，就是不断重复着亲近与疏远，从而找到让彼此都不会受伤的距离。——伊坂幸太郎",
            "当你真心渴望某样东西时，整个宇宙都会联合起来帮助你完成。——《牧羊少年奇幻之旅》",
            "你可以选择放弃，也可以选择坚持。——《百年孤独》",
            "真正的对手是你最想赢，也最想输给他的那个人。——《一代宗师》",
            "没有不可治愈的伤痛，没有不能结束的沉沦。——约翰·肖尔斯",
            "我思故我在。——笛卡尔",
            "人性一个最特别的弱点，就是在意别人如何看待自己。——叔本华",
            "重要的不是治愈，而是带着病痛活下去。——加缪",
            "最高的道德是秘密，真正的智慧是沉默。——爱伦·坡",
            "世界以痛吻我，要我报之以歌。——泰戈尔",
            "皮格马利翁效应--（自证预言）期望影响结果：当他人（尤其是权威者）对某人抱有高期待时，此人的表现会无意识地向期待靠拢。例子：老师认为某学生聪明并给予关注，学生成绩显著提升。",
            "斯图尔特效应--（自证预言）期望影响结果：当某人对自己的表现感到满意时，他会无意识地对自己的表现进行改进。例子：学生对自己的表现感到满意，于是学习更加努力。",
            "破窗效应--环境暗示的力量：若环境中出现小问题未被修复，可能引发更严重的失控。例子：一扇破窗若不修补，周围窗户可能陆续被打破。",
            "达克效应（邓宁-克鲁格效应）认知偏差：能力不足者容易高估自己，而高能力者可能低估自己。曲线：从“愚昧之巅”跌入“绝望之谷”，最终走向“开悟之坡”。",
            "习得性无助长期挫败后的放弃：经历多次失败后，即使有机会改变，人也会选择被动接受。实验：电击笼中的狗最终放弃逃脱。",
            "负罪感：对他人的错误和伤害产生的强烈不满和痛苦。实验：当某人被发现犯了错误时，会产生强烈的负罪感。",
            "负罪感的影响：负罪感可能导致人们对自己的行为和表现产生不满和不满。实验：当某人被发现犯了错误时，会产生强烈的负罪感。",
            "心理小游戏--优点轰炸--目标：提升自信与团队凝聚力。规则：围坐一圈，每人轮流被其他人说出其优点，被评价者只能倾听并记录。",
            "心理小游戏--挑战游戏--目标：增强团队合作能力。规则：围坐一圈，每人轮流提出挑战，被评价者只能回答并记录。",
            "心理小游戏--情绪漂流瓶--目标：释放情绪压力。操作：匿名写下近期烦恼投入“漂流瓶”，随机抽取并集体讨论解决建议。",
            "心理小游戏--团队建设--目标：增强团队凝聚力。规则：围坐一圈，每人轮流提出团队建设建议，被评价者只能回答并记录。",
            "角色互换辩论--目标：培养同理心。规则：针对争议话题（如“是否应该996”），正反方交换立场进行辩论。",
            // 可以添加更多名言
        ];

        sandbox.addEventListener('mousedown', (e) => {
            const x = e.offsetX;
            const y = e.offsetY;
            const key = `${x}-${y}`;
            const count = (clickCounts.get(key) || 0) + 1;
            clickCounts.set(key, count);

            if (count === 1) {
                createIndentation(x, y, 1);
            } else if (count === 2) {
                createIndentation(x, y, 2);
            } else if (count === 3) {
                createBubble(x, y);
            }
        });

        let isDragging = false;
        let lastX, lastY;

        sandbox.addEventListener('mousedown', (e) => {
            isDragging = true;
            lastX = e.offsetX;
            lastY = e.offsetY;
        });

        sandbox.addEventListener('mousemove', (e) => {
            if (isDragging) {
                createSandTrench(lastX, lastY, e.offsetX, e.offsetY);
                lastX = e.offsetX;
                lastY = e.offsetY;
                if (Math.random() < 0.1) { // 10% 的概率弹出气泡
                    createBubble(e.offsetX, e.offsetY);
                }
            }
        });

        sandbox.addEventListener('mouseup', () => {
            isDragging = false;
        });

        function createIndentation(x, y, depth) {
            const indentation = document.createElement('div');
            indentation.style.position = 'absolute';
            indentation.style.left = `${x}px`;
            indentation.style.top = `${y}px`;
            indentation.style.width = `${20 * depth}px`;
            indentation.style.height = `${20 * depth}px`;
            indentation.style.borderRadius = '50%';
            indentation.style.backgroundColor = `rgba(0, 0, 0, 0.${depth})`;
            sandbox.appendChild(indentation);
        }

        function createBubble(x, y) {
            const bubble = document.createElement('div');
            bubble.style.position = 'absolute';
            bubble.style.left = `${x + 20}px`;
            bubble.style.top = `${y - 20}px`;
            bubble.style.padding = '10px';
            bubble.style.backgroundColor = 'white';
            bubble.style.border = '1px solid #ccc';
            bubble.style.borderRadius = '5px';
            // 提高 z-index 值，确保气泡显示在最上层
            bubble.style.zIndex = 1000; 
            bubble.textContent = quotes[Math.floor(Math.random() * quotes.length)];

            // 打印日志，确认气泡是否创建
            console.log('创建气泡:', bubble);

            // 检查 sandbox 容器是否存在
            if (sandbox) {
                sandbox.appendChild(bubble);
            } else {
                console.error('未找到 sandbox 容器');
            }

            // 5 秒后移除气泡
            setTimeout(() => {
                if (sandbox && bubble.parentNode === sandbox) {
                    sandbox.removeChild(bubble);
                }
            }, 5000);
        }

        function createSandTrench(startX, startY, endX, endY) {
            const trench = document.createElement('div');
            trench.style.position = 'absolute';
            trench.style.left = `${Math.min(startX, endX)}px`;
            trench.style.top = `${Math.min(startY, endY)}px`;
            trench.style.width = `${Math.abs(endX - startX)}px`;
            trench.style.height = `${Math.abs(endY - startY)}px`;
            trench.style.backgroundColor = 'rgba(0, 0, 0, 0.1)';
            sandbox.appendChild(trench);
        }
    </script>
</body>
<!-- 添加提示气泡 -->
<div id="double-click-tip" style="position: fixed; bottom: 320px; right: 20px; padding: 10px; background-color: white; border: 1px solid #ccc; border-radius: 5px; z-index: 1000;">
    如果感到无聊，三击屏幕空白处试试·_·
</div>

<script>
    // 监听双击事件
    document.addEventListener('dblclick', () => {
        const tip = document.getElementById('double-click-tip');
        if (tip) {
            tip.remove();
        }
    });
</script>
</html>